/**
 * Program   :   MailUtils.java
 * Author    :   shadow guo
 * Create    :   2010-1-11 上午07:12:08
 *
 * Copyright 2008 by Tongfu Information Technology Co. Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Tongfu Information Technology Co. Ltd. ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Tongfu Information Technology Co. Ltd.
 * 
 */

/**
 * 
 */
package com.tongfusoft.utils.mail;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.mail.internet.MimeUtility;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.HtmlEmail;

import com.tongfusoft.exception.EmailException;
import com.tongfusoft.utils.CryptoUtils;

/**
 * @author shadowguo
 * 
 */
public class MailServicesImpl implements MailServices {
	private static Log log = LogFactory.getLog(MailServicesImpl.class);

	public static final String SUCC = "succ";
	public static final String FAIL = "fail";
	private static final String DESKEY = "1001110723473208";

	private String mailServer;
	private String userMail;
	private String passwordMail;
	private boolean hasAuthentication = true;

	
	

	public boolean isHasAuthentication() {
		return hasAuthentication;
	}

	public void setHasAuthentication(boolean hasAuthentication) {
		this.hasAuthentication = hasAuthentication;
	}

	/**
	 * @return the mailServer
	 */
	public String getMailServer() {
		return mailServer;
	}

	/**
	 * @param mailServer the mailServer to set
	 */
	public void setMailServer(String mailServer) {
		this.mailServer = mailServer;
	}

	/**
	 * @return the userMail
	 */
	public String getUserMail() {
		return userMail;
	}

	/**
	 * @param userMail the userMail to set
	 */
	public void setUserMail(String userMail) {
		this.userMail = userMail;
	}

	/**
	 * @return the passwordMail
	 */
	public String getPasswordMail() {
		return passwordMail;
	}

	/**
	 * @param passwordMail the passwordMail to set
	 */
	public void setPasswordMail(String passwordMail) {
		this.passwordMail = CryptoUtils.desDecryptFromBase64(passwordMail, DESKEY
				.getBytes());;
	}


	@Override
	public boolean sendEmail(MailBean mb) {
		boolean result = false;

		filterMailBean(mb);
		try {
			HtmlEmail email = new HtmlEmail();
			email.setHostName(mb.getMailServser());
			email.setSSL(mb.isSSL());
			email.setSmtpPort(mb.getSmtpPort());
			if(this.hasAuthentication){
				email.setAuthentication(mb.getFrom(),mb.getPassword());
			}
			email.addTo(mb.getTo());
			email.setCharset(mb.getCharSet());
			email.setFrom(mb.getFrom());
			email.setSubject(mb.getSubject());

			List cclist = mb.getCc();
			if (cclist != null) {
				for (int i = 0; i < cclist.size(); i++) {
					email.addCc((String) cclist.get(i));
				}
			}

			if (StringUtils.isNotEmpty(mb.getHtmlMsg())) {
				email.setHtmlMsg(mb.getHtmlMsg());
			}

			if (StringUtils.isNotEmpty(mb.getTextMsg())) {
				email.setTextMsg(mb.getTextMsg());
			}

			EmailAttachment attachment = null;

			Iterator iter = mb.getFile().entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry entry = (Map.Entry) iter.next();
				attachment = addFileAccessories((String) entry.getKey(),
						(String) entry.getValue());
				email.attach(attachment);
			}

			List urlList = mb.getUrl();
			for (int i = 0; i < urlList.size(); i++) {
				attachment = adduUrlAccessories((String) urlList.get(i));
				email.attach(attachment);
			}

			email.setDebug(true);
			email.send();
			result = true;

		} catch (Exception e) {
			log.error("send email error ,errorinfo:" + e.getMessage());
			throw new EmailException(e);
		}

		return result;
	}

	private EmailAttachment adduUrlAccessories(String sUrl)
			throws MalformedURLException {
		URL url = new URL(sUrl);
		EmailAttachment attchment = new EmailAttachment();
		attchment.setURL(url);
		attchment.setDisposition(EmailAttachment.ATTACHMENT);

		attchment.setDescription(url.getFile());
		attchment.setName(url.getFile());
		return attchment;
	}

	private EmailAttachment addFileAccessories(String filename,
			String file) {
		EmailAttachment attchment = new EmailAttachment();
		attchment.setPath(file);
		attchment.setDisposition(EmailAttachment.ATTACHMENT);

		try {
			attchment.setDescription(MimeUtility.encodeText(filename));
			attchment.setName(MimeUtility.encodeText(filename));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return attchment;

	}

	private void filterMailBean(MailBean mb) {
		if (StringUtils.isEmpty(mb.getFrom())) {
			mb.setFrom(this.getUserMail());
			mb.setPassword(this.getPasswordMail());
		}

		if (StringUtils.isEmpty(mb.getMailServser())) {
			mb.setMailServser(this.getMailServer());
		}

	}

	@Override
	public Map<String,List<MailBean>> sendEmail(List<MailBean> mbList){
		List<MailBean> successList = new ArrayList<MailBean>();
		List<MailBean> failList = new ArrayList<MailBean>();
		
		if(mbList != null){
			for(MailBean mb : mbList){
				try{
					if(this.sendEmail(mb)){
						successList.add(mb);
					}else{
						failList.add(mb);
					}
				}catch(Exception e){
					log.error(e.getMessage());
					failList.add(mb);
				}
			}
		}
		
		Map<String,List<MailBean>> result = new HashMap<String,List<MailBean>>();
		result.put("success", successList);
		result.put("fail", failList);
		
		return result;
	}

	public static void main(String arg[]){
		System.out.println(CryptoUtils.desEncryptToBase64("12345678", DESKEY.getBytes()));
		System.out.println(CryptoUtils.desDecryptFromBase64("GD2NHcYstOGLl/6tzBthog==", DESKEY.getBytes()));
	}
}
